<template>
  <el-form ref="formRef" :model="form" :rules="formRules" label-position="top" class="q-form">
    <el-row :gutter="16">
      <el-col :span="item.col" v-for="(item, index) in formConfig" :key="index">
        <el-form-item :label="item.label" v-if="item.type === 'text'" :prop="item.prop">
          <el-input v-model="form[item.prop]" :disabled="isRead" :placeholder="item.placeholder || '请输入'" />
        </el-form-item>
        <el-form-item :label="item.label" v-else-if="item.type === 'password'" :prop="item.prop">
          <el-input
            v-model="form[item.prop]"
            type="password"
            :disabled="isRead"
            :placeholder="item.placeholder || '请输入'"
          />
        </el-form-item>
        <el-form-item :label="item.label" v-else-if="item.type === 'select'" :prop="item.prop">
          <el-select
            style="width: 100%"
            v-model="form[item.prop]"
            :disabled="isRead"
            :clearable="true"
            :placeholder="item.placeholder"
          >
            <el-option
              v-for="option in item.selectOption"
              :key="option.value"
              :label="option.text"
              :value="option.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item :label="item.label" v-else-if="item.type === 'select-tree'" :prop="item.prop">
          <el-tree-select
            v-model="form[item.prop]"
            :data="item.apiData"
            :render-after-expand="false"
            v-bind="item?.componentProps || {}"
            style="width: 240px"
          />
        </el-form-item>
        <el-form-item :label="item.label" v-else-if="item.type === 'date'" :prop="item.prop">
          <el-date-picker
            style="width: 100%"
            v-model="form[item.prop]"
            type="date"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            :placeholder="item.placeholder || '请选择'"
            :disabled="isRead"
          />
        </el-form-item>
        <el-form-item :label="item.label" v-else-if="item.type === 'date-rang'" :prop="item.prop">
          <el-date-picker
            style="width: 100%"
            v-model="form[item.prop]"
            type="daterange"
            :start-placeholder="item.startPlaceholder"
            :end-placeholder="item.endPlaceholder"
            :disabled="isRead"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
          />
        </el-form-item>
      </el-col>

      <el-col :span="4" v-if="showFilterButtons">
        <el-form-item label="占位" class="empty">
          <el-button type="primary" icon="Search" @click="onSearchFn">搜索</el-button>
          <el-button icon="Refresh" @click="resetForm">重置</el-button>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>

<script setup>
import { cloneDeep, forEach } from 'lodash-es'
const emits = defineEmits(['register'])
import { ref } from 'vue'

const form = ref({})
const formConfig = ref([])
const isRead = ref(false)
const formRules = ref({})
const formRef = ref(null)
const showFilterButtons = ref(false)
const onSearchFn = ref(() => {})
const onResetFn = ref(() => {})

const validate = () => {
  return new Promise((resolve, reject) => {
    formRef.value.validate((valid, fields) => {
      if (valid) {
        resolve(true)
      } else {
        console.error(fields)
        resolve(false)
      }
    })
  })
}

const resetForm = () => {
  formRef.value.resetFields()
  onResetFn.value()
}

const getForm = () => {
  return cloneDeep(form.value)
}

const setForm = data => {
  form.value = cloneDeep(data)
}

const initDataByDataRang = item => {
  form.value[item.prop] = []
  formConfig.value.push(item)
}
const initDataBySelectTree = (item, index) => {
  form.value[item.prop] = ''
  if (!item.apiData) {
    item.apiData = []
  }
  if (item.api && typeof item.api === 'function') {
    item.api().then(res => {
      formConfig.value[index].apiData = res?.data || []
    })
  }
  formConfig.value.push(item)
}
const initDataByOthers = item => {
  form.value[item.prop] = ''
  formConfig.value.push(item)
}

const initData = async data => {
  const { config, isFilter, onSearch, onReset } = data
  if (isFilter !== undefined) {
    showFilterButtons.value = isFilter
  }
  if (onSearch !== undefined) {
    onSearchFn.value = onSearch
  }
  if (onReset !== undefined) {
    onResetFn.value = onReset
  }
  forEach(config, (item, index) => {
    switch (item.type) {
      case 'date-rang':
        initDataByDataRang()
        break
      case 'select-tree':
        initDataBySelectTree(item, index)
        break
      default:
        initDataByOthers(item)
    }
    formRules.value[item.prop] = item.rules
  })
}

emits('register', { initData, validate, getForm, setForm })
</script>

<style scoped lang="scss">
.q-form {
  .empty {
    ::v-deep(.el-form-item__label) {
      opacity: 0;
    }
  }
}
</style>
